package com.example.myapplication4;

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;

public class MainActivity extends AppCompatActivity {

    private WebSocketClient webSocketClient;
    private String TAG = "main";
    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                try {
                    MediaExtractor mediaExtractor = new MediaExtractor();
                  //  mediaExtractor.setDataSource("my.aac");

                    URI uri = URI.create("ws://58.33.27.44:21079/tsinglive/863053810662855_1_realtime?token=8991ad95c24c5977eda6a3e02abc3ab1&type=1&duration=600");
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        if(Objects.isNull(webSocketClient) || !webSocketClient.isOpen()){
                            webSocketClient = new WebSocketClient(uri) {
                                @Override
                                public void onOpen(ServerHandshake handshakedata) {
                                    Log.i("TAG","sucess");

                                }

                                @Override
                                public void onMessage(String message) {
                                    byte[] bytes = Base64.decode(message, Base64.DEFAULT);

                                    Log.i("on message",message);
                                }

                                @Override
                                public void onMessage(ByteBuffer bytes) {
                                    Log.i("bytes",ByteBufUtil.hexDump(Unpooled.wrappedBuffer(bytes)));
                                }

                                @Override
                                public void onClose(int code, String reason, boolean remote) {
                                    Log.i("TAG","sucess");

                                }

                                @Override
                                public void onError(Exception ex) {
                                    Log.i("TAG","sucess");

                                }
                            };

                        }
                    }
                    try {
                        webSocketClient.connect();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    //socket init
                    executorService.scheduleAtFixedRate(()->{
                        if(webSocketClient.isOpen()){
                            webSocketClient.send("0");
                        }
                    },2,5, TimeUnit.SECONDS);

                    //implementation "org.java-websocket:Java-WebSocket:1.4.0"
                    MediaFormat mediaFormat = null;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        mediaFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC,44100,1);
                    }
                    String mediaMime = mediaFormat.getString(MediaFormat.KEY_MIME);
                    Log.i("TAG", "decodeAacToPcm: mimeType: " + mediaMime);
                    MediaCodec codec = MediaCodec.createDecoderByType(mediaMime);
                    codec.configure(mediaFormat, null, null, 0);
                    codec.start();
                    ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
                    ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
                    final long kTimeOutUs = 10_000;
                    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                    boolean sawInputEOS = false;
                    boolean sawOutputEOS = false;


                    try {
                        while (!sawOutputEOS) {
                            if (!sawInputEOS) {
                                int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
                                if (inputBufIndex >= 0) {
                                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
                                    int sampleSize = mediaExtractor.readSampleData(dstBuf, 0);
                                    if (sampleSize < 0) {
                                        Log.i(TAG, "saw input EOS.");
                                        sawInputEOS = true;
                                        codec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                    } else {
                                        codec.queueInputBuffer(inputBufIndex, 0, sampleSize, mediaExtractor.getSampleTime(), 0);

                                        //44khz 1s
                                        //extractor.advance();
                                    }
                                }
                            }

                            int outputBufferIndex = codec.dequeueOutputBuffer(info, kTimeOutUs);
                            if (outputBufferIndex >= 0) {
                                // Simply ignore codec config buffers.
                                if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                                    Log.i(TAG, "audio encoder: codec config buffer");
                                    codec.releaseOutputBuffer(outputBufferIndex, false);
                                    continue;
                                }

                                if (info.size != 0) {
                                    ByteBuffer outBuf = codecOutputBuffers[outputBufferIndex];
                                    outBuf.position(info.offset);
                                    outBuf.limit(info.offset + info.size);
                                    byte[] data = new byte[info.size];
                                    outBuf.get(data);
                                    //这里应该往audioTracker写就可以播放。
                                    //fosDecoder.write(data);
                                }

                                codec.releaseOutputBuffer(outputBufferIndex, false);
                                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                                    Log.i(TAG, "saw output EOS.");
                                    sawOutputEOS = true;
                                }
                            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                                codecOutputBuffers = codec.getOutputBuffers();
                                Log.i(TAG, "output buffers have changed.");
                            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                                MediaFormat oformat = codec.getOutputFormat();
                                Log.i(TAG, "output format has changed to " + oformat);
                            }
                        }
                    } finally {
                        Log.i(TAG, "decodeAacToPcm finish");
                        codec.stop();
                        codec.release();
//                        extractor.release();
//                        fosDecoder.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
